﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Forms;


namespace DataFileApp
{
    public class JsonTreeViewTrans
    {
        public List<NodeInfo> LsNodeInfos = new List<NodeInfo>();

        string strJson = string.Empty;
        System.Windows.Forms.TreeView treeView;
        /// <summary>
        /// 绑定json字符串到节点树
        /// </summary>
        /// <param name="strJson">json字符串</param>
        /// <param name="treeView">节点树</param>
        public void JsonBindingToTreeView(string strJson, System.Windows.Forms.TreeView treeView)
        {
            this.strJson = strJson;
            this.treeView = treeView;
            Binding();
        }

        private void Binding()
        {
            try
            {
                treeView.Nodes.Clear();//清空Node
                if (IsJOjbect(strJson))
                {
                    JObject jo = (JObject)JsonConvert.DeserializeObject(strJson);
                    foreach (var joitem in jo)
                    {
                        TreeNode jotree;

                        if (joitem.Value.GetType() == typeof(JObject))
                        {
                            jotree = new TreeNode(joitem.Key);
                            AddTreeChildNode(ref jotree, joitem.Value.ToString());
                            treeView.Nodes.Add(jotree);
                            CreatNewNode(jotree, joitem.Value.ToString());
                        }
                        else if (joitem.Value.GetType() == typeof(JArray))
                        {

                            if (IsVarArray(joitem.Value.ToString()))
                            {
                                jotree = new TreeNode(joitem.Key);
                                AddTreeChildNode(ref jotree, joitem.Value.ToString());
                                treeView.Nodes.Add(jotree);
                                CreatNewNode(jotree, joitem.Value.ToString());
                            }
                            else
                            {
                                jotree = new TreeNode(joitem.Key);
                                treeView.Nodes.Add(jotree);
                                CreatNewNode(jotree, joitem.Value.ToString());
                            }

                        }
                        else if (joitem.Value.GetType() == typeof(JValue))
                        {
                            jotree = new TreeNode(joitem.Key);
                            treeView.Nodes.Add(jotree);
                            CreatNewNode(jotree, joitem.Value.ToString());
                        }
                        else
                        {
                            jotree = new TreeNode(joitem.Key);
                            treeView.Nodes.Add(jotree);
                            CreatNewNode(jotree, joitem.Value.ToString());
                        }
                    }
                }
                if (IsJArray(strJson))
                {

                    JArray ja = (JArray)JsonConvert.DeserializeObject(strJson);
                    foreach (JObject items in ja)
                    {
                        TreeNode tree = new TreeNode();
                        foreach (var jaitem in items)
                        {
                            TreeNode jatree;
                            if (jaitem.Value.GetType() == typeof(JObject))
                            {
                                jatree = new TreeNode(jaitem.Key);
                                AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                                tree.Nodes.Add(jatree);
                                CreatNewNode(jatree, jaitem.Value.ToString());
                            }
                            else if (jaitem.Value.GetType() == typeof(JArray))
                            {
                                if (IsVarArray(jaitem.Value.ToString()))
                                {
                                    jatree = new TreeNode(jaitem.Key);
                                    AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                                    tree.Nodes.Add(jatree);
                                    CreatNewNode(jatree, jaitem.Value.ToString());
                                }
                                else
                                {
                                    jatree = new TreeNode(jaitem.Key);
                                    tree.Nodes.Add(jatree);
                                    CreatNewNode(jatree, jaitem.Value.ToString());
                                }
                            }
                            else if (jaitem.Value.GetType() == typeof(JValue))
                            {
                                jatree = new TreeNode(jaitem.Key);
                                tree.Nodes.Add(jatree);
                                CreatNewNode(jatree, jaitem.Value.ToString());
                            }
                            else
                            {
                                jatree = new TreeNode(jaitem.Key);
                                tree.Nodes.Add(jatree);
                                CreatNewNode(jatree, jaitem.Value.ToString());
                            }
                        }
                        treeView.Nodes.Add(tree);
                        CreatNewNode(tree, "");
                    }
                }
                treeView.ExpandAll();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        /// <summary>
        /// TreeView新增的节点添加到List集合中
        /// </summary>
        /// <param name="CurrentNode">当前添加的节点</param>
        /// <param name="value">节点树的值</param>
        public void CreatNewNode(TreeNode CurrentNode, string value)
        {
            int nodes = CurrentNode.Nodes.Count;
            NodeInfo nodeInfo = new NodeInfo();
            ////nodeInfo.NodeValue = value;
            nodeInfo.CurrentNode = CurrentNode;
            nodeInfo.CurrentNode.Tag = value;
            var info = LsNodeInfos.Where(t => CurrentNode == t.CurrentNode);
            if (!info.Any())
            {
                LsNodeInfos.Add(nodeInfo);
            }


            for (int i = 0; i < nodes; i++)
            {
                NodeInfo nodeInfo1 = new NodeInfo();
                ////  nodeInfo1.NodeValue = value;
               
                nodeInfo1.CurrentNode = CurrentNode.Nodes[i];
                nodeInfo1.CurrentNode.Tag = value;
                var info1 = LsNodeInfos.Where(t => CurrentNode.Nodes[i] == t.CurrentNode);
                if (!info1.Any())
                {
                    LsNodeInfos.Add(nodeInfo1);
                }
            }



            //for (int i = 0; i < nodes; i++)
            //{
            //    NodeInfo nodeInfo = new NodeInfo();
            //    nodeInfo.NodeValue = value;
            //    nodeInfo.CurrentNode = CurrentNode;
            //    var info = LsNodeInfos.Where(t => CurrentNode == t.CurrentNode);
            //    if (!info.Any())
            //    {
            //        LsNodeInfos.Add(nodeInfo);
            //    }
            //}

        }
        public void AddNewNodes(TreeNode CurrentNode)
        {
            if (CurrentNode.Nodes.Count > 0)
            {
                for (int i = 0; i < CurrentNode.Nodes.Count; i++)
                {
                    //递归将每个节点保存到字典
                    AddNewNodes(CurrentNode.Nodes[i]);

                    NodeInfo nodeInfo1 = new NodeInfo();
                    ////nodeInfo1.NodeValue = "";
                    
                    nodeInfo1.CurrentNode = CurrentNode.Nodes[i];
                  
                    var info1 = LsNodeInfos.Where(t => CurrentNode.Nodes[i] == t.CurrentNode);
                    if (!info1.Any())
                    {
                        LsNodeInfos.Add(nodeInfo1);
                    }
                }
            }
            else
            {
                NodeInfo nodeInfo = new NodeInfo();
                ////nodeInfo.NodeValue = "";
                
                nodeInfo.CurrentNode = CurrentNode;
              
                var info = LsNodeInfos.Where(t => CurrentNode == t.CurrentNode);
                if (!info.Any())
                {
                    LsNodeInfos.Add(nodeInfo);
                }
            }





        }

        /// <summary>
        /// 添加子节点
        /// </summary>
        /// <param name="parantNode">json键</param>
        /// <param name="value">json值</param>
        public void AddTreeChildNode(ref TreeNode parantNode, string value)
        {
            if (IsJOjbect(value))
            {
                JObject jo = (JObject)JsonConvert.DeserializeObject(value);
                foreach (var joitem in jo)
                {
                    TreeNode jotree;
                    if (joitem.Value.GetType() == typeof(JObject))
                    {
                        jotree = new TreeNode(joitem.Key);
                        AddTreeChildNode(ref jotree, joitem.Value.ToString());
                        parantNode.Nodes.Add(jotree);
                        CreatNewNode(jotree, joitem.Value.ToString());
                    }
                    else if (joitem.Value.GetType() == typeof(JArray))
                    {
                        if (IsVarArray(joitem.Value.ToString()))
                        {
                            jotree = new TreeNode(joitem.Key);
                            AddTreeChildNode(ref jotree, joitem.Value.ToString());
                            parantNode.Nodes.Add(jotree);
                            CreatNewNode(jotree, joitem.Value.ToString());
                        }
                        else
                        {
                            jotree = new TreeNode(joitem.Key);
                            parantNode.Nodes.Add(jotree);
                            CreatNewNode(jotree, joitem.Value.ToString());
                        }
                    }
                    else
                    {
                        jotree = new TreeNode(joitem.Key);
                        parantNode.Nodes.Add(jotree);
                        CreatNewNode(jotree, joitem.Value.ToString());
                    }
                }
            }
            if (IsJArray(value))
            {

                JArray ja = (JArray)JsonConvert.DeserializeObject(value);
                //数组元素索引
                int arrayIndex = 0;
                foreach (JObject item in ja)
                {

                    //数组元素显示在Treeview中的节点名称
                    TreeNode tree = new TreeNode($"Array{arrayIndex}");
                    arrayIndex++;
                    parantNode.Nodes.Add(tree);
                    CreatNewNode(tree, "");

                    foreach (var jaitem in item)
                    {
                        TreeNode jatree;
                        if (jaitem.Value.GetType() == typeof(JObject))
                        {
                            jatree = new TreeNode(jaitem.Key);
                            AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);
                            CreatNewNode(jatree, jaitem.Value.ToString());
                        }
                        else if (jaitem.Value.GetType() == typeof(JArray))
                        {
                            jatree = new TreeNode(jaitem.Key);
                            AddTreeChildNode(ref jatree, jaitem.Value.ToString());
                            tree.Nodes.Add(jatree);
                            CreatNewNode(jatree, jaitem.Value.ToString());
                        }
                        else
                        {
                            jatree = new TreeNode(jaitem.Key);
                            tree.Nodes.Add(jatree);
                            CreatNewNode(jatree, jaitem.Value.ToString());
                        }
                    }
                }

            }

        }

        public bool IsJOjbect(string value)
        {
            try
            {
                JObject ja = JObject.Parse(value);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool IsJArray(string value)
        {
            try
            {
                JArray ja = JArray.Parse(value);
                return true;

            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public bool IsVarArray(string value)
        {
            try
            {
                bool a = true;
                JArray ja = JArray.Parse(value);
                foreach (var item in ja)
                {
                    if (item.GetType() != typeof(JObject))
                    {
                        a = false;
                        break;
                    }
                }
                return a;
            }
            catch (Exception)
            {
                return false;
            }
        }



        /// <summary>
        /// 将TreeView转换为json字符串
        /// </summary>
        /// <param name="treeView"></param>
        /// <returns></returns>
        public string ConvertTreeViewToJson(System.Windows.Forms.TreeView treeView)
        {
            var treeViewItems = new Dictionary<object, object>();

            foreach (TreeNode item in treeView.Nodes)
            {
                treeViewItems.Add(item.Text, Recursion(item));
            }
            return JsonConvert.SerializeObject(treeViewItems, Newtonsoft.Json.Formatting.Indented);
        }

        public Dictionary<string, object> Recursion(TreeNode item)
        {
            if (item.Nodes.Count > 0)
            {
                var children = new Dictionary<string, object>();

                foreach (TreeNode childItem in item.Nodes)
                {
                    var grandChildren = Recursion(childItem);

                    children.Add(childItem.Text.ToString(), grandChildren);
                }
                return children;
            }

            return new Dictionary<string, object>();
        }


        /// <summary>
        ///
        /// </summary>
        /// <param name="treeView1"></param>
        /// <returns></returns>
        public string DynamicCreatePropertyMesBody(System.Windows.Forms.TreeView treeView1)
        {
            // ExpandoObject MainBody = new ExpandoObject();
            // TraverseTreeNodes(treeView1.Nodes, ref MainBody);
            Dictionary<string, object> MainBody = new Dictionary<string, object>();
            TraverseTreeNodes(treeView1.Nodes, ref MainBody);
            return JsonConvert.SerializeObject(MainBody);

        }
        private void TraverseTreeNodes(TreeNodeCollection nodes, ref Dictionary<string, object> MainBody)
        {
            try
            {
                foreach (TreeNode node in nodes)
                {
                    // 处理当前节点
                    // 判断当前节点是否有子节点
                    if (node.Nodes.Count > 0)
                    {
                        Dictionary<string, object> TempBody = new Dictionary<string, object>();
                        // ExpandoObject TempBody = new ExpandoObject();
                        TraverseTreeNodes(node.Nodes, ref TempBody);
                        try
                        {
                            //((IDictionary<string, object>)MainBody).Add(node.Text, TempBody);

                            MainBody.Add(node.Text, TempBody);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message);
                        }

                    }
                    else
                    {
                        foreach (var item in LsNodeInfos)
                        {
                            string GetFatherNode = "";
                            if (node.Parent == null)
                            {
                                GetFatherNode = "无";
                            }
                            else
                            {
                                GetFatherNode = node.Parent.Text;
                            }
                            if (node == item.CurrentNode)
                            {
                                try
                                {
                                   //// ((IDictionary<string, object>)MainBody).Add(item.CurrentNode.Text, item.NodeValue);
                                    ((IDictionary<string, object>)MainBody).Add(item.CurrentNode.Text, item.CurrentNode.Tag);
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.Message);
                                }
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"设置出错：{ex.Message}");
            }
        }


        public Customer TransTreeViewToArray(TreeNodeCollection nodes)
        {
            Customer customer = new Customer();
            foreach (TreeNode Rootnode in nodes)   //Array0
            {
                foreach (TreeNode node in Rootnode.Nodes)
                {
                    CustomerObject customerObject = new CustomerObject();
                    //判断是否为customerObject类型集合
                    if (node.Text.Contains("Array") && node.Parent.Parent == null)
                    {
                        customerObject.ModbusStartAddress = int.Parse(node.Nodes[0].Tag.ToString());
                        foreach (TreeNode nNode in node.Nodes[1].Nodes)   //items/Array0
                        {
                            Item item = null;
                            if (nNode.Text.Contains("Array"))
                            {
                                item = new Item();
                                item.Name = nNode.Nodes[0].Tag.ToString();
                                item.DataType = nNode.Nodes[1].Tag.ToString();
                                item.ModubusType = nNode.Nodes[2].Tag.ToString();
                                item.ModbusAddressLenth = int.Parse(nNode.Nodes[3].Tag.ToString());
                            }
                            customerObject.items.Add(item);
                        }
                        if (Rootnode.Text== "Input")
                        {
                            customer.Input.Add(customerObject);
                        }
                        else
                        {
                            customer.Output.Add(customerObject);
                        }
                    }
                }
            }
            return customer;
        }
    }
}
